home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 112 / EnigmaAmiga112CD.iso / dalla rivista / giochi in rete / sorgenti_amislate / display.c < prev    next >
C/C++ Source or Header  |  1995-07-30  |  18KB  |  487 lines

  1. /* This module was hacked painfully from a Commodore AmigaMail example. */
  2.  
  3. /* ScreenDisplayModes.c - V36 Screen Displaymode selector example
  4.    hacked by Jeremy Friesner 12/30/94 -- do not distribute! It ain't pretty! */
  5.         
  6. #include <stdio.h>        
  7. #include <string.h>
  8. #include <intuition/intuition.h>
  9. #include <intuition/screens.h>
  10. #include <intuition/gadgetclass.h>
  11. #include <libraries/gadtools.h>
  12. #include <graphics/displayinfo.h>
  13. #include <graphics/text.h>
  14. #include <exec/memory.h>
  15. #include <exec/ports.h>
  16.  
  17. #include <clib/exec_protos.h>
  18. #include <clib/intuition_protos.h>
  19. #include <clib/graphics_protos.h>
  20. #include <clib/gadtools_protos.h>
  21. #include <clib/alib_protos.h>
  22.  
  23. #include <pragmas/exec_pragmas.h>
  24. #include <pragmas/intuition_pragmas.h>
  25. #include <pragmas/graphics_pragmas.h>
  26. #include <pragmas/gadtools_pragmas.h>
  27.  
  28. #include "AmiSlate.h"
  29.  
  30. #define SWITCH 888
  31. #define QUIT   999
  32.  
  33. extern struct IntuitionBase *IntuitionBase;
  34. extern struct GfxBase *GfxBase;
  35. extern struct Library *GadToolsBase;
  36. extern struct Library *SysBase;
  37. extern BOOL BAGA;
  38. extern BOOL BDos20;
  39. extern int screentype;
  40. extern int nSynchPaletteMode;
  41. extern char szVersionString[];
  42.  
  43. int nWorkbenchDepth;
  44.  
  45. /* module-private functions */
  46. __stkargs static struct Screen *ShowDisplayModes(struct List * dlist, 
  47.             WORD bRHeight, WORD bRWidth, BYTE bRDepth);
  48. static struct Screen *OpenAScreen(struct DimensionInfo * di, UBYTE * name,
  49.                ULONG overscantype, int nDepth);
  50. static struct Window *OpenAWindow(struct Screen * screen, ULONG overscantype);
  51.  
  52. struct DisplayNode {
  53.     struct Node dn_Node;
  54.     struct DimensionInfo dn_Dimensioninfo;
  55. };
  56.  
  57. /* The workbench compatible pens we'll use for that New Look. */
  58. static UWORD dri_Pens[] = {0, 1, 1, 2, 1, 3, 1, 0, 3, ~0};
  59.  
  60. struct EasyStruct failedES =
  61. {
  62.     sizeof(struct EasyStruct), 0, "SDM",
  63.     "%s",
  64.     "OK",
  65. };
  66.  
  67.  
  68. struct Screen *GetDisplay(WORD wRHeight, WORD wRWidth, BYTE bRDepth)
  69. {
  70.     struct List *dlist;
  71.     struct DisplayNode *dnode;
  72.     struct DisplayNode *wnode, *nnode;
  73.      struct Screen *sScreen;
  74.      struct Node NWorkbenchNode;
  75.      char szWorkBench[] = "Workbench";            
  76.     ULONG modeID;
  77.     ULONG skipID;
  78.     ULONG result;
  79.     struct DisplayInfo displayinfo;
  80.     struct NameInfo nameinfo;
  81.  
  82.      /* Note:  This node is statically allocated */    
  83.     NWorkbenchNode.ln_Name = szWorkBench;
  84.  
  85.     if (dlist = AllocMem(sizeof(struct List), MEMF_CLEAR)) 
  86.     {
  87.          NewList(dlist);
  88.     
  89.             AddTail(dlist, &NWorkbenchNode);
  90.           
  91.          /*
  92.          * Don't want duplicate entries in the list for the
  93.          * 'default monitor', so we'll skip the the videomode
  94.          * for which default.monitor is the alias.
  95.          */
  96.  
  97.          /* INVALID_ID indicates the beginning and the end
  98.           * of the list of available keys.
  99.           */
  100.          modeID = INVALID_ID;
  101.  
  102.          GetDisplayInfoData(NULL, (UBYTE *) & displayinfo, sizeof(struct DisplayInfo),
  103.                                         DTAG_DISP, LORES_KEY);
  104.          if (displayinfo.PropertyFlags & DIPF_IS_PAL)
  105.             skipID = PAL_MONITOR_ID;
  106.          else
  107.             skipID = NTSC_MONITOR_ID;
  108.          while ((modeID = NextDisplayInfo(modeID)) != INVALID_ID) 
  109.          {
  110.            if ((modeID & MONITOR_ID_MASK) != skipID) 
  111.            {
  112.                 /*
  113.                  * For this example,only 'named' keys are accepted.  Others
  114.                  * which have no description are left out
  115.                   * even though they may be available.
  116.                   * HAM and EXTRAHALFBRIGHT are examples of this.
  117.                   * If needed a name could be made like '320x400 HAM Interlace'.
  118.                   */
  119.  
  120.               if (result = GetDisplayInfoData(NULL,(UBYTE *) & nameinfo,
  121.                 sizeof(struct NameInfo), DTAG_NAME, modeID)) 
  122.           {
  123.                  result = GetDisplayInfoData(NULL,(UBYTE *) & displayinfo,
  124.                 sizeof(struct DisplayInfo), DTAG_DISP,modeID);
  125.                  if (!(displayinfo.NotAvailable)) 
  126.                  {
  127.                      if (dnode = (struct DisplayNode *) 
  128.                         AllocMem(sizeof(struct DisplayNode),MEMF_CLEAR)) 
  129.                      {
  130.                         result = GetDisplayInfoData(NULL,(UBYTE *) &
  131.                        (dnode->dn_Dimensioninfo),sizeof(struct DimensionInfo),
  132.                      DTAG_DIMS, modeID);
  133.                            /* to keep it short: if NOMEM,
  134.                  * just don't copy
  135.                  */
  136.                         if (dnode->dn_Node.ln_Name = AllocMem(
  137.                             strlen(nameinfo.Name)+ 1, MEMF_CLEAR))
  138.                                  strcpy(dnode->dn_Node.ln_Name, nameinfo.Name);
  139.                            AddTail(dlist, (struct Node *) dnode);
  140.                          }
  141.                          else 
  142.                          {
  143.                            EasyRequest(NULL, &failedES, NULL, "Out of memory");
  144.                                         
  145.                            /* Force modeID to INVALID to break */
  146.                            modeID = INVALID_ID;
  147.                         }
  148.                  }
  149.               }
  150.            }
  151.          }
  152.       sScreen = ShowDisplayModes(dlist, wRWidth, wRHeight, bRDepth);    
  153.  
  154.       /* Cleanup! */                
  155.       /* Start with second in List because the first was statically allocated */
  156.       wnode = (struct DisplayNode *) dlist->lh_Head->ln_Succ;
  157.       while (nnode = (struct DisplayNode *) (wnode->dn_Node.ln_Succ)) 
  158.       {
  159.         if (wnode->dn_Node.ln_Name)
  160.            FreeMem(wnode->dn_Node.ln_Name,strlen(wnode->dn_Node.ln_Name) +1);
  161.            
  162.         Remove((struct Node *) wnode);
  163.         FreeMem(wnode, sizeof(struct DisplayNode));
  164.         wnode = nnode;
  165.       }
  166.       FreeMem(dlist, sizeof(struct List));
  167.     } 
  168.     else
  169.     EasyRequest(NULL, &failedES, NULL, "Out of memory");
  170.   return(sScreen); 
  171. }
  172.  
  173.  
  174.  
  175.  
  176. __stkargs static struct Screen *
  177. ShowDisplayModes(struct List * dlist, WORD wRWidth, WORD wRHeight, BYTE bRDepth)
  178. {
  179.     struct Screen *screen = NULL;
  180.     struct Window *window;
  181.     struct Gadget *glist, *gadget, *hitgadget;
  182.     struct DrawInfo *drawinfo;
  183.     struct TextFont *defaultfont;
  184.     struct TextAttr *textattr;
  185.     struct IntuiMessage *imsg;
  186.     struct NewGadget *ng;
  187.      STRPTR pnames[] = {"Both", "Remote", "Local", "Neither", NULL};
  188.     int nDepth;
  189.     void *vi;
  190.     char sBuffer[200];
  191.     ULONG iclass, icode;
  192.     struct DisplayNode *dnode;
  193.     struct DimensionInfo *dimensioninfo;
  194.     ULONG curmode = 0;
  195.     BOOL ABORT = TRUE, OK, BWriteScreenInfo = TRUE;
  196.     int i;
  197.     
  198.      /* 0 = set to our default, otherwise use remote screen val as current */
  199.      if (bRDepth == -1) 
  200.      {
  201.          bRDepth = (BAGA*5)+3;
  202.          BWriteScreenInfo = FALSE;
  203.      }
  204.      
  205.     if (ng = AllocMem(sizeof(struct NewGadget), MEMF_CLEAR)) 
  206.     {
  207.         if (textattr = AllocMem(sizeof(struct TextAttr), MEMF_CLEAR)) 
  208.         {
  209.             if (textattr->ta_Name = AllocMem(48, MEMF_CLEAR)) 
  210.             {
  211.                   dnode = (struct DisplayNode *) dlist->lh_Head;
  212.                   OK = FALSE;
  213.                   screen = LockPubScreen("Workbench");
  214.                   if (screen == NULL) return(NULL);
  215.                   nWorkbenchDepth = screen->RastPort.BitMap->Depth;
  216.                         nDepth = nWorkbenchDepth;
  217.                         drawinfo = GetScreenDrawInfo(screen);
  218.                   defaultfont = drawinfo->dri_Font;
  219.                   strcpy(textattr->ta_Name,defaultfont->tf_Message.mn_Node.ln_Name);
  220.  
  221.                   textattr->ta_YSize = defaultfont->tf_YSize;
  222.                   textattr->ta_Style = defaultfont->tf_Style;
  223.                   textattr->ta_Flags = defaultfont->tf_Flags;
  224.  
  225.                   if (window = OpenAWindow(screen, OSCAN_TEXT))
  226.                   {
  227.                       vi = GetVisualInfo(screen, TAG_END);
  228.                       
  229.                         if (gadget = CreateContext(&glist)) 
  230.                      {
  231.                          /* ListView Gadget */
  232.             ng->ng_LeftEdge = window->BorderLeft + 10;
  233.             ng->ng_TopEdge  = window->BorderTop + 10;
  234.             ng->ng_Width    = window->Width - (window->BorderLeft + 10) -
  235.                                                   (window->BorderRight + 10);
  236.             ng->ng_Height   = window->Height - (window->BorderTop + 10) - (25 * BWriteScreenInfo) -
  237.                       (window->BorderBottom + 10) - (4 + defaultfont->tf_YSize + 2);
  238.                         ng->ng_TextAttr = textattr;
  239.                         ng->ng_GadgetText = NULL;
  240.                         ng->ng_VisualInfo = vi;
  241.                         ng->ng_GadgetID   = 1;
  242.                         ng->ng_Flags      = PLACETEXT_ABOVE;
  243.                         gadget =    CreateGadget(LISTVIEW_KIND, gadget,
  244.                               ng, GTLV_Labels, dlist,
  245.                               GTLV_ShowSelected, NULL,
  246.                               GTLV_Selected, curmode,
  247.                               TAG_END);
  248.  
  249.             /* OK Gadget */
  250.                            ng->ng_TopEdge += gadget->Height + 7 + (BDos20 * defaultfont->tf_YSize);
  251.                         ng->ng_LeftEdge = ng->ng_LeftEdge + ng->ng_Width - 80;
  252.                         ng->ng_Width = 80;
  253.                            ng->ng_Height = defaultfont->tf_YSize + 8;
  254.                         ng->ng_GadgetID = 2;
  255.                         ng->ng_GadgetText = "OK";
  256.                         ng->ng_VisualInfo = vi;
  257.                         ng->ng_Flags = PLACETEXT_IN;
  258.                         gadget = CreateGadget(BUTTON_KIND, gadget, ng, TAG_END);
  259.                                                         
  260.                         /* Slider Gadget */
  261.                         ng->ng_Width = window->Width - 130;
  262.                         ng->ng_LeftEdge =    (window->BorderLeft + 25);
  263.                                                                
  264.             ng->ng_Height = window->Height - ng->ng_TopEdge - defaultfont->tf_YSize - 6 - (25 * BWriteScreenInfo);
  265.             if (ng->ng_Height < 4) ng->ng_Height = 4;
  266.             
  267.                         ng->ng_GadgetID = 3;
  268.                         ng->ng_GadgetText = "BitMap Depth";
  269.                         ng->ng_VisualInfo = vi;
  270.                         ng->ng_Flags = PLACETEXT_BELOW;
  271.                         gadget = CreateGadget(SLIDER_KIND, gadget, ng, GA_Disabled, TRUE,
  272.                                     GTSL_Min, 1, GTSL_Max, (BAGA*3)+5,
  273.                                     GTSL_Level, nWorkbenchDepth, GTSL_LevelFormat,
  274.                                     "%1ld", GTSL_MaxLevelLen, 1,
  275.                                     TAG_END);
  276.     
  277.                          AddGList(window, glist, -1, -1, NULL);
  278.                          RefreshGList(glist, window, NULL, -1);
  279.                            GT_RefreshWindow(window, NULL);
  280.                            ABORT = FALSE;
  281.                      } 
  282.                      else
  283.                      EasyRequest(window, &failedES, NULL,"Can't create gadget context");
  284.                        
  285.                      /* Put in Remote dimension message if appropriate */
  286.                      if (BWriteScreenInfo == TRUE)
  287.                      {
  288.                          SetAPen(window->RPort, 1);
  289.                          Move(window->RPort, 70, window->Height-17);
  290.                          Text(window->RPort, "Your partner is using a",23);
  291.                          Move(window->RPort, 45, window->Height-6);
  292.                          sprintf(sBuffer, "%u x %u, %u bitplane screen",
  293.                                      wRWidth, wRHeight, bRDepth);
  294.                          Text(window->RPort,sBuffer, strlen(sBuffer));
  295.                      }
  296.                      
  297.                      do 
  298.                      {
  299.                         WaitPort(window->UserPort);
  300.                         while (imsg = GT_GetIMsg(window->UserPort)) 
  301.                         {
  302.                           iclass = imsg->Class;
  303.                           icode = imsg->Code;
  304.                           hitgadget = (struct Gadget *) imsg->IAddress;
  305.                           GT_ReplyIMsg(imsg);
  306.  
  307.                           switch (iclass) 
  308.                           {
  309.                             case GADGETUP:
  310.                               switch (hitgadget->GadgetID)
  311.                               {
  312.                                   case 1:
  313.                                         dnode = (struct DisplayNode *) dlist->lh_Head;
  314.                                         if (icode == 0)
  315.                                                  {
  316.                                                          /* Disable Slider Gadget */
  317.                                                          GT_SetGadgetAttrs(gadget, window, NULL, GA_Disabled, TRUE, TAG_END);
  318.                                                  }
  319.                                                  else
  320.                                                  {
  321.                                                      /* Enable it */
  322.                                                      /* Disable Slider Gadget */
  323.                                                      GT_SetGadgetAttrs(gadget, window, NULL, GA_Disabled, FALSE,  TAG_END);
  324.                                                  }
  325.                                                  for (i = 0; i < icode; i++)
  326.                                         {
  327.                                           dnode = (struct DisplayNode *) dnode->dn_Node.ln_Succ;
  328.                                                       curmode = i;
  329.                                                  }
  330.                                              break;
  331.                                              
  332.                                  case 2:
  333.                                            OK = TRUE;
  334.                                    break;
  335.                               }
  336.                               break;
  337.  
  338.                                      case IDCMP_MOUSEMOVE:
  339.                                          if (hitgadget->GadgetID == 3) nDepth = icode;
  340.                               break;
  341.                              
  342.                             case CLOSEWINDOW:
  343.                               ABORT = TRUE;
  344.                               break;
  345.                               
  346.                             case VANILLAKEY:
  347.                               switch(icode)
  348.                               {
  349.                                   case 13:
  350.                                       OK = TRUE;        /* Return pressed */
  351.                                       break;
  352.                                   case 27:
  353.                                       ABORT = TRUE;    /* Escape pressed */
  354.                                       break;
  355.                               }
  356.                               break;
  357.                           }
  358.                         }
  359.                      } 
  360.                      while (ABORT == FALSE && OK == FALSE);
  361.                      
  362.                      CloseWindow(window);
  363.                      FreeVisualInfo(vi);
  364.                      FreeGadgets(glist);
  365.                      FreeMem(textattr->ta_Name, 48);
  366.                      FreeMem(ng, sizeof(struct NewGadget));
  367.                      FreeMem(textattr, sizeof(struct TextAttr));
  368.  
  369.                      FreeScreenDrawInfo(screen, drawinfo);
  370.                      UnlockPubScreen("Workbench",screen);
  371.  
  372.                      if (ABORT == TRUE) return(NULL);
  373.                                      
  374.                      if (OK == TRUE) 
  375.                      {
  376.                          if (strcmp(dnode->dn_Node.ln_Name,"Workbench") == 0)
  377.                          {
  378.                              screentype = USE_WORKBENCHSCREEN;
  379.                              screen = NULL;
  380.                          }
  381.                          else
  382.                          {
  383.                              dimensioninfo = &(dnode->dn_Dimensioninfo);
  384.                              screen = OpenAScreen(dimensioninfo,
  385.                                           dnode->dn_Node.ln_Name,
  386.                                           OSCAN_TEXT,nDepth);  
  387.                             screentype = USE_CUSTOMSCREEN;
  388.                         }
  389.                      }
  390.                      return(screen);
  391.                   } 
  392.                   else
  393.                   {
  394.                      EasyRequest(NULL, &failedES, NULL,"Can't open window");
  395.                   }
  396.                
  397.                
  398.                } 
  399.             else
  400.             {
  401.                 EasyRequest(NULL, &failedES, NULL, "Out of memory");
  402.                     FreeMem(ng, sizeof(struct NewGadget));
  403.                 FreeMem(textattr, sizeof(struct TextAttr));
  404.                }
  405.          } 
  406.          else
  407.          {
  408.             EasyRequest(NULL, &failedES, NULL, "Out of memory");
  409.                 FreeMem(ng, sizeof(struct NewGadget));
  410.          }
  411.     } 
  412.     else
  413.     {
  414.         EasyRequest(NULL, &failedES, NULL, "Out of memory");
  415.     }
  416.     return(NULL);
  417. }
  418.  
  419.  
  420. /*
  421.  * It's advised to use one of the overscan constants and
  422.  * STDSCREENWIDTH and STDSCREENHEIGHT. For this example however, we'll
  423.  * skip all that an use QueryOverscan to get the rectangle describing the
  424.  * requested overscantype and pass that as the displayclip description.
  425.  * Actually, since we pass the standard rectangle from the display database,
  426.  * it is equivalent to the prefered:
  427.  *
  428.  * screen = OpenScreenTags(NULL,
  429.  *                         SA_DisplayID, di->Header.DisplayID,
  430.  *                         SA_Overscan, overscantype,
  431.  *                         SA_Width, STDSCREENWIDTH,
  432.  *                         SA_Height, STDSCREENHEIGHT,
  433.  *                         SA_Title, name,
  434.  *                         SA_Depth, 2,
  435.  *                         SA_SysFont, 1,
  436.  *                         SA_Pens, dri_Pens,
  437.  *                         TAG_END);
  438.  */
  439.  
  440. struct Screen *
  441. OpenAScreen(struct DimensionInfo * di, UBYTE * name, ULONG overscantype, int nDepth)
  442. {
  443.  
  444.     struct Rectangle rectangle;
  445.  
  446.     /* Can't fail, already made sure it's a valid displayID */
  447.     QueryOverscan(di->Header.DisplayID, &rectangle, overscantype);
  448.  
  449.  
  450.     return (OpenScreenTags(NULL,
  451.                            SA_DisplayID, di->Header.DisplayID,
  452.                            SA_DClip, &rectangle,
  453.                            SA_Title, szVersionString+5,
  454.                            SA_Depth, nDepth,
  455.                            SA_SysFont, 1,   /* Use the prefered WB screen font */
  456.                            SA_Pens, dri_Pens,
  457.                            TAG_END));
  458. }
  459.  
  460. static struct Window *
  461. OpenAWindow(struct Screen * screen, ULONG overscantype)
  462. {
  463.      const int nWindowHeight = 200, nWindowWidth = 320;
  464.      int nWindowTop, nWindowLeft;
  465.      
  466.      if (screen->Width < nWindowWidth) return(NULL);
  467.      if (screen->Height < nWindowHeight) return(NULL);
  468.      
  469.      /* center window on screen */      
  470.      nWindowTop =  (screen->BarHeight + 1)+
  471.                   (((screen->Height-(screen->BarHeight+1))-nWindowHeight))/2;
  472.  
  473.      nWindowLeft = ((screen->Width-nWindowWidth))/2;
  474.                           
  475.      return (OpenWindowTags(NULL,
  476.                            WA_Top, nWindowTop,
  477.                            WA_Left, nWindowLeft,
  478.                            WA_Height, nWindowHeight,
  479.                            WA_Width, nWindowWidth,
  480.                            WA_IDCMP, CLOSEWINDOW | BUTTONIDCMP | LISTVIEWIDCMP | SLIDERIDCMP | IDCMP_VANILLAKEY,
  481.                            WA_Flags, WINDOWCLOSE | ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET,
  482.                            WA_Title, "Select a display resolution",
  483.                            TAG_END));
  484. }
  485.  
  486.  
  487.